Translated by visionNoob, KNU https://github.com/insurgent92/CS231N_17_KOR_SUB
오늘은 정말 배울게 많습니다. 시작하도록 하겠습니다!
오늘은 생성 모델(Generative Models) 에 대해서 배워보도록 하겠습니다.
수업에 앞서 공지사항을 전달하도록 하겠습니다.
중간 고사 채점 결과는 Gradescope를 통해 이번주에 공개될 예정입니다.
그리고 과제 3은 다음주 금요일 (5월 26) 까지임을 명심하도록 하세요
추가 크레딧을 받기 위한 HyperQuest 기한은 5월 21일 일요일 까지 입니다.
그리고 포스터 세션은 6월 6일 12시부터 3시 까지 진행됩니다.
오늘을 주제를 조금 바꿔서 비지도 학습(unsupervised leraning)에 대해 배울 것입니다.
특히 비지도학습의 일종인 생성 모델(Generative models)에 대해서 배워보겠습니다.
세가지 종류의 생성모델을 다룰 것입니다.
pixelRNN 과 pixelCNN, variational autoencoders(VAE)
그리고 Generative Adversarial networks(GAN) 입니다.
지금까지 CS231n 수업에서는 다양한 지도학습(supervised learning) 문제를 다뤄왔습니다.
지도 학습에서는 데이터 X, 레이블 Y가 있었습니다.
지도 학습의 목적은 데이터 X를 레이블 Y에 매핑시키는 함수를 배우는 것입니다.
레이블은 다양한 형태를 띄고 있었습니다.
가령 분류(classification) 문제의 예를 들어보자면 이미지가 입력이고, 출력은 클래스 레이블 Y 입니다. 카테고리죠
Object Detection 문제에서는 입력은 이미지로 동일하지만 출력은 각 객체들의 bounding box 입니다.
Semantic segmentation 에서는 모든 픽셀 마다, 각 픽셀이 속하는 카테고리를 결정해야 했습니다.
Image captioning에 대해서도 배워보았습니다. 레이블이 한 문장이었습니다.
문장은 자연어(natural language)의 형태를 띄고 있었습니다.
비지도 학습에서는 레이블이 없는 학습 데이터만 가지고 데이터에 숨어있는 기본적인 구조를 학습시켜야 합니다.
비지도 학습의 예로는 군집화(clustering)이 있습니다. 군집화에 대해서 이미 아시는 분들도 계실 것입니다.
군집화의 목표는 일정 metric을 가지고 유사한 데이터들끼리 묶어(group)주는 것입니다.
가령 K-means clustering이 있습니다.
비지도 학습의 또다른 예는 차원 축소(dimensionality reduction) 입니다.
차원 축소 문제에서는 학습 데이터가 가장 많이 퍼져있는 축을 찾아내는 것입니다.
그렇게 찾아낸 축은 데이터에 숨어있는 구조의 일부분이라고 할 수 있습니다.
이 방법은 데이터의 차원을 감소시키는데 사용할 수 있습니다. 데이터는 축소된 차원에서도 중요한 정보들을 잘 보존해야 합니다.
가령 여기 3차원 데이터가 있습니다. 이 데이터의 두 개의 축을 찾아낼 것입니다.
2차원으로 차원을 축소시키기 위해서죠 (projection)
비지도 학습의 또 다른 예는 데이터의 feature representation을 학습하는 것입니다.
우리는 앞서 분류문제와 같은 supervised loss를 이용한 feature representation을 배웠습니다.
여기에는 분류를 위한 레이블(개, 고양이)가 있고 Softmax loss 등을 사용합니다.
그렇게 네트워크를 학습시켜서 , FC7 레이어의 특징을 데이터의 feature representation으로 사용할 수 있습니다.
비지도 학습의 경우에는, 잠시 후에 더 자세히 다룰 Autoencoders가 있습니다.
AE의 Loss는 입력 데이터를 얼마나 잘 재구성했는지 인데, 이를 이용해서도 특징들을 학습시킬 수 있습니다.
AE를 사용하면 추가적인 레이블 없이도 feature representation을 학습시킬 수 있는 것입니다.
그리고 마지막으로 비지도 학습의 예에는 분포 추정(density estimation) 이 있습니다.
이는 데이터가 가진 기본적인(underlyting) 분포를 추정하는 방법입니다.
가령 오른쪽 맨 위의 1차원 점들이 있습니다. 그리고 이 점들의 분포를 가우시안(Gaussian)으로 추정합니다.
그리고 하단의 예제의 경우에는 2차원 데이터입니다. 이번에는 2차원 데이터의 분포를 추정합니다.
점들이 더 많이 밀집되어 있는 곳의 분포가 더 크도록 이들의 분포를 적절히 모델링할 수 있습니다.
교사/비교사 학습의 차이점을 요약해보면, 교사학습의 경우에는 레이블을 통해 X에서 Y로 가능 함수 매핑을 학습합니다.
비교사 학습의 경우에는 레이블이 없고 대신에 데이터의 숨겨진 구조를 학습합니다. 군집화(grouping),
변화의 중심 축(axis of variation), 혹은 데이터의 밀도추정 등이 있습니다.
비교사 학습은 아주 광범하고 흥미있는 분야입니다.
인기있는 이유 중 하나는, 데이터에 대한 비용이 아주 적기 때문 입니다. 레이블이 없기 때문에 데이터를 아주 많이 모을 수 있습니다.
레이블이 있는 데이터보다 데이터를 수직하기 훨씬 수월합니다.
하지만 비교사 학습은 여전히 (비교적) 많은 연구가 이루어진 분야는 아닙니다. 여전히 풀어야 할 문제가 많죠
하지만 여러분이 데이터에 숨겨진 구조들을 성공적으로 잘 학습할 수만 있다면
시각 세계(visual world.)의 구조를 이해할 수 있는 아주 좋은 발판을 마련할 수 있는 좋은 기회일 수 있습니다.
지금까지 비교사 학습에 관한 개괄이었습니다.
오늘은 비교사 학습 중에서도 생성 모델을 집중적으로 다룰 예정입니다.
생성 모델은 비교사 학습의 일종으로, 생성 모델의 목적은 동일한 분포에서 새로운 샘플들을 생성해 내는 것입니다.
자 여기 학습 데이터가 있습니다. 이 데이터는 분포 P_data로부터 나온 데이터들입니다.
우리가 하고자 하는 것은 p_model을 학습시키는 것입니다. p_model이 p_data와 같은 데이터를 생성하도록 하는 것이죠
이를 위해선 p_model 과 p_data가 유사하게 만들어야만 합니다.
생성 모델에서는 "분포 추정"을 다뤄야 합니다.
앞서 말씀드렸듯이, 학습 데이터의 근본이 되는 분포를 추정해야 합니다. 이는 비교사 학습의 핵심 문제이기도 합니다.
분포 추정에는 몇 가지 전략이 있을 수 있습니다.
하나는, 생성 모델 P_model의 분포가 어떨지를 명시적(explicitly) 으로 정의해 주는 경우입니다.
혹은(다른 하나는), 간접적(implicit)인 방법도 있습니다.
모델이 p_model에서 샘플을 만들어내도록 학습시키는 것은 동일하지만, 이번에는 p_model의 분포를 정의하지 않습니다.
그렇다면 생성 모델이 왜 중요할까요? 왜 생성 모델이 비교사 학습에서 중요한 문제인 것일까요?
생성 모델을 가지고 할 수 있는 것들은 정말 많습니다.
데이터 분포로부터, 아주 사실적인(realistic) 샘플들을 생성해 낼 수만 있다면 이를 이용하여 아주 많은 것들을 할 수 있습니다.
다음 이미지들은 생성 모델에 의해 생성된 샘플들입니다.
생성 모델을 이미지에 적용하면 super resolution이나 colorization과 같은 테스크에 적용할 수 있습니다.
colorization의 예를 보면, 지갑의 밑그림만 그려 놓으면 생성 모델이 색을 채워줘서 지갑이 실제로 어떻게 생겼을지 알 수 있습니다.
생성 모델은 강화 학습을 이용한 시뮬레이션이나 플래닝 (planning)을 위한 시계열 데이터 생성에도 이용될 수 있습니다.
강화학습(reinforcement learning)은 다음 시간에 저 자세히 다뤄볼 예정입니다.
생성 모델을 학습하면 latent representations을 추정해 볼 수도 있습니다.
데이터의 잠재적인 특징들(latent features)을 잘 학습시켜 놓으면 추후 다른 테스크에도 아주 유용하게 쓰일 수 있습니다.
생성 모델의 종류를 살펴보겠습니다. 생성 모델은 다음과 같은 taxonomy로 분류를 해 볼 수 있습니다.
앞서 명시적(explicit)/간접적(implicit) 분포 모델에 대해서는 말씀드렸습니다.
그리고 그 밑으로 다양한 서브 카테고리로 더 많이 쪼갤 수도 있습니다.
이 taxonomy는 Ian Goodfellow의 GAN 튜토리얼에 있습니다.
여러분이 생성 모델의 다양한 갈래를 알고싶다면 이 taxonomy를 참고하시면 아주 유용할 것입니다.
오늘은 생성모델 중에서도, 오늘날 연구가 아주 활발하게 이루어지고 있는 세가지 모델만 배울 것입니다.
우선, pixelRNN/CNN에 대해서 간단히 설명드릴 것입니다(1).
그 다음은 variational autoencoders(VAE) 입니다(2).
이 두가지 모델은 명시적 분포 모델에 속합니다.
PixelRNN/CNN은 "계산이 가능한 확률모델 사용" (Tractable density)에 속하고
VAE는 "근사적 밀도추정(Approximate density)" 에 속합니다.
그리고 마지막으로 generative adversarial networks (GAN)에 대해서 배워볼 것입니다(3).
GANs은 "간접적인 분포 추정(implicit density)"의 한 유형입니다.
자 그럼 pixelRNN/CNN 부터 시작해봅시다.
pixelRNN/CNN은 fully visible brief networks 의 일종입니다.
여기에서는 밀도를 명시적으로 정의하고 모델링합니다.
자 이제 이미지 데이터 X가 있습니다. 그리고 이미지 x에 대한 우도(likelihood)인 p(x)를 모델링할 것입니다. 이 모델의 경우에는
체인룰(chain rule)로 우도(likelihood) p(x)를 1차원 분포들간의 곱의 형태로 분해(decompose)합니다.
이렇게 분해하면, 픽셀 x_i에 대해서 각각 p(x_i │conditions) 를 정의할 수 있습니다.
conditions은 이전의 모든 픽셀 x1부터 x_(i-1) 이 붙게 됩니다.
이미지 내의 모든 픽셀에 대한 joint likelihood는 모든 픽셀의 likelihoods의 곱의 형태가 됩니다.
우도(likelihood) p(x) 를 정의했으니 이제 모델을 학습시키려면 학습 데이터의 우도를 최대화시키면 됩니다.
픽셀 값에 대한 분포를 보면 p(x_i given 이전의 모든 픽셀) 입니다. 이는 분포가 아주 복잡합니다.
어떻게 모델링하면 좋을까요?
우리는 앞서, 복잡한 변환(transformation)을 수행하길 원한다면 Neural Networks를 사용했습니다.
Neural networks가 이러한 복잡한 변환들을 표현하기에는 제격입니다.
이제는 이 복잡한 함수를 표현하기 위해서 신경망을 이용할 것입니다.
이 문제에서 여러분이 알아두셔야 할 점은
nerural network를 쓰는 것 까진 좋지만 한가지 문제가 있습니다. 픽셀들의 순서를 어떻게 다뤄야 할까요?
우리의 분포 p(현재 픽셀 given 모든 이전 픽셀) 에서 도대체 "모든 이전 픽셀"이 의미하는 바가 무엇일까요?
지금부터 그것을 살펴볼 것입니다.
PixelRNN은 2016에 제안된 논문입니다.
PixelRNN은 기본적으로 이 문제를 풀기 위해 고안된 방법입니다. 이 모델이 어떻게 동작하는지 살펴보면
우선 이미지의 좌상단 코너에 있는 픽셀부터 생성을 시작해보도록 합니다.
여기 보이시는 그리드가 이미지의 픽셀들이라고 보시면 됩니다. 이제 좌상단 코너부터 시작해 보도록 하겠습니다.
이 모델은 여기보이시는 화살표 방향으로의 연결성을 기반으로 순차적으로 픽셀을 생성해냅니다.
그리고 이러한 방향성을 기반으로한 픽셀들간의 종속성을 RNN을 이용하여 모델링합니다.
RNN 모델 중에서도 우리가 앞서 다룬 LSTM 모델을 이용합니다.
이런 방식으로 대각선 아래 방향으로 계속 내려가면서 픽셀들을 생성해 냅니다.
이들의 종속성은 연결성을 기반으로 한 채 말이죠
이 방법은 정말 잘 동작하긴 하지만 한가지 단점이 있습니다. 바로 순차적인 생성 방식이기 때문에 아주 느리다는 점이죠
가령 새로운 이미지를 생성하고자 한다면 여러번의 feed forward를 거쳐야 합니다.
모든 픽셀이 생성될 때 까지 반복적으로 네트워크를 수행해야 합니다.
pixelRNN 조금 뒤에 pixelCNN이라는 또 다른 모델이 제안되었습니다.
pixelCNN의 기본적인 문제 세팅 자체는 pixelRNN과 동일합니다.
왼쪽 코너에서부터 새로운 이미지를 생성할 것입니다. pixelCNN과의 차이점이 있다면
모든 종속성을 고려하여 모델링하는 RNN 대신에 pixelCNN은 CNN으로 모델링한다는 점입니다.
이제 우리는 컨텍스트 영역에서 CNN을 사용할 것입니다.
이제는 픽셀을 생성할때 특정 픽셀만을 고려합니다.
그림의 회색 지역이 이미 생성된 픽셀들인데, 이들 중에서도 특정 영역만을 사용하여 다른 픽셀 값을 생성합니다.
자 PixelCNN에서는 각 픽셀에서 CNN을 수행합니다.
CNN에서는 출력 값을 가지고 softmax loss 를 계산할 수 있습니다.
여기에서는 레이블이 0-255 가 될 것입니다. 우리는 학습 데이터로 likelihood가 최대화하도록 학습시킬 수 있습니다.
이렇게 픽셀을 생성하는 과정에서 각 픽셀 값은 정답 값(ground truth)를 가지고 있을 것입니다.
이 정답값은 0-255 사이의 분류(classification) 문제를 풀기 위한 레이블 이라고 볼 수 있습니다.
따라서 softmax loss로 학습시킬 수 있는 것입니다.
그리고 이런 학습 과정은 기본적으로 likelihood를 최대화하는 것과 같습니다.
질문 있나요?
[학생이 질문]
질문은 "우리는 지금 비지도 학습을 다루고 있는데 왜 여기에는 classification label이 들어가는지" 입니다.
우리가 Loss를 계산할때 쓰는 레이블은 입력 학습 데이터를 사용할 뿐입니다.
추가적인 레이블은 필요가 없습니다.
우리가 레이블을 추가적으로 만들어낸 것이 아니고 입력 데이터 그 자체를 사용했을 뿐입니다.
[학생이 질문]
질문은 "이 방법이 bag of words같은 방법인지" 입니다.
bag of words하고는 거리가 멉니다.
이 방법은 이미지 내의 각 픽셀들의 분포를 알고싶은 것입니다.
이를 위해 likelihood를 최대화하도록 잘 학습을 시켜서 입력인 학습 데이터를 잘 생성하도록 하는 것이죠
이를 위해서 입력 데이터를 Loss로 사용하는 것입니다.
pixelCNN을 사용하면 pixelRNN보다 학습이 더 빠릅니다.
왜냐하면 Train time에서는 (모든 픽셀들에 대해서) 학습 데이터의 likelihood를 최대화하는 것이기 때문입니다.
학습 데이터는 이미 우리가 알고있는 값이기 때문에 학습 과정을 병렬화시킬 수 있습니다.
하지만 새로운 이미지를 생성해야 하는 test time에서는 여전히 코너에서부터 시작해야 하고
이 생성 방법에 대한 새로운 제안은 없었기 때문에 여전히 현재 픽셀을 생성하려면 이전 픽셀부터 순차적으로 처리해야 합니다.
따라서 학습은 더 빠를지 몰라도 이미지를 생성하는데 걸리는 시간은 여전히 느립니다.
질문 있나요?
[학생이 질문]
질문은 "이 방법은 첫 픽셀(의 분포)을 어떤 값으로 정하는냐에 민감해지지 않은지" 입니다.
예 맞습니다. 처음 픽셀의 분포는 이후 모든 분포에 영향을 미치기 때문에 중요합니다.
초기 픽셀의 분포를 선택하는 방법은, Training time에는 학습 데이터의 픽셀 값을 가져오면 됩니다.
Test time(생성) 에는 uniform distribuion을 사용할 수도 있고, 첫 픽셀만 학습 데이터에서 가져올 수도 있습니다.
초기 값만 설정하면 나머지 값들은 알고리즘을 수행하면 됩니다.
질문 있나요?
[학생이 질문]
질문은 "한번에 모든 픽셀을 예측하는 대신에 Chain rule 방식으로 이를 정의하는 방법은 없는지" 입니다. (#issue_8)
앞으로 이와 관련된 모델을 보게 될 테지만
chain rule은 계산 가능한(tractable) 확률모델을 기반으로 likelihood를 직접 최적화시킬 수 있도록 도와줍니다.
자 여기 이미지가 pixelCNN으로 생성한 이미지들입니다.
왼쪽은 CIFAR-10을 생성한 결과입니다. 결과를 보면 자연 이미지의 분포를 잘 포착해낸 것 같아 보입니다.
자연 이미지에서 나올법한 이미지들을 잘 생성해 냈습니다.
그리고 오른쪽은 ImageNet으로 학습시킨 결과입니다. 이 결과 또한 자연스러워 보이기는 합니다.
하지만 여전히 개선의 여지는 많습니다.
원래의 학습 이미지와 분명히 차이점이 존재하고. 실제 의미론적인 부분이 명확하지 않음을 알 수 있습니다.
요약하자면, pixelRNN/CNN은 likelihood p(x)를 명시적으로 계산하는 방법입니다.
우리가 최적화시킬 수 있는 분포(밀도)를 명시적으로 정의합니다.
이렇게 분포를 명시적으로 정의하는 경우의 추가적인 장점이 있다면 "evaludation metic"이 존재한다는 것입니다.
우리가 데이터를 통해 계산할 수 있는 likelihood를 이용하면 생성된 샘플이 얼마나 잘 만들어졌는지를 평가할 수 있습니다.
그리고 꽤 좋은 샘플 이미지들을 생성하기는 하지만 여전히 아주 활발히 연구되고 있는 분야입니다.
이 방법의 가장 큰 단점은 생성 과정이 순차적이기 때문에 상당히 느리다는 점입니다.
그리고 pixelRNN/CNN은 가령, 음성생성 (audio generation) 에도 사용될 수 있습니다.
음성생성에 관련 예제를 온라인에서 쉽게 찾아보실 수 있습니다. 다만, 음성생성의 경우에도 아주 느리다는 단점은 여전합니다.
그리고 pixelCNN의 성능을 개선시기키 위한 아주 많은 연구들이 진행되어 오고 있습니다.
아키텍쳐 혹은 Loss 함수를 새롭게 설계한다던가 학습 과정의 다양한 트릭을 적용하는 등 여러 시도가 있었습니다.
PixelCNN에 더 관심이 있으신 분들은 PixelCNN 논문을 참고하시기 바랍니다.
또한 2017년도에 나온 PixelCNN++ 와 같은 더 향상된 버전의 논문들도 많으니 참고해 주시기 바랍니다.
자 이제부터는 다른 종류의 생성모델인 variational autoencoders(VAE)에 대해서 배워보겠습니다.
우리가 지금까지 살펴본 pixelCNN은 여기 있는 정의처럼 "계산이 가능한 확률모델"을 기반으로 합니다.
이를 기반으로 학습 데이터의 likelihood를 직접 최적화시킵니다.
VAE의 경우에는 직접 계산이 불가능한(intractable) 확률 모델을 정의합니다.
우리는 이제 추가적인 잠재 변수(latent vatiable) z를 모델링할 것입니다. 이에 대해 더 자세히 알아봅시다.
VAE에서는 data likelihood p(x)가 적분의 형태를 띄고 있습니다.
가능한 모든 z값에 대한 기댓값을 구하는 방식입니다.
하지만 이는 문제가 됩니다. 이 식을 직접 최적화시킬 수는 없습니다.
대신에 이 likelihood(p(x))의 하안(lower bound) 를 구해서(detrive) 최적화시켜야만 합니다.
질문 있나요?
질문은 "z가 무엇인지" 입니다.
z는 잠재 변수(latent variable) 입니다. 앞으로 더 자세히 다룰 내용입니다.
자 그럼 우선 VAE의 배경을 먼저 살펴보겠습니다.
VAE는 autoencoders(AEs) 라는 비교사 학습 모델과 관련이 있습니다.
그러니 우선은 autoencoders에 대해서 설명을 드리고 나서
VAE가 AE와 어떤 연관이 있고, 이를 통해 어떻게 데이터를 생성할 수 있는지를 알아보겠습니다.
우선 autoencoders는 데이터 생성이 목적이 아닙니다.
AE는 레이블되지 않은 학습 데이터로부터 저차원의 feature representation을 학습하기 위한 비교사 방법입니다.
여기 보시는 바와 같이 입력 데이터 x가 있습니다. 우리는 어떤 특징 "z"를 학습하길 원하는 것입니다.
여기에서 encoder는 입력 데이터 x를 특징 z로 변환하는 매핑 함수의 역할을 합니다.
Encoder는 다양한 방법으로 설계할 수 있습니다.
일반적으로는 Neural network를 사용합니다. 하지만 autoencoder는 아주 오래전부터 존재했던 모델입니다.
2000대에는 Linear + nonlinearity를 이용한 모델을 주로 사용했으며
그 이후로는 FC-layer를 사용한 더 깊은 네트워크가, 그리고 더 나아가 CNN을 사용하기에 까지 이르렀습니다.
입력 데이터 x가 있고, x를 특징 z로 매핑시킬 것입니다.
일반적으로 z는 x보다 작읍니다. 이로 인해 기본적으로 AE를 통해 차원 축소의 효과를 기대할 수 있습니다.
그렇다면 질문입니다. "우리는 왜 차원 축소를 하고싶은 것일까요?"
왜 z가 x보다 작아지길 원하는 걸까요?
[학생이 답변]
답변은 "z가 데이터 x의 가장 중요한 특징들을 잘 담고 있어야 하기 때문" 이라고 했습니다. 예 맞습니다.
우리는 z가 데이터 x의 중요한 요소들이 담겨있는 특징들을 학습하길 원합니다.
그렇다면 "우리가 어떻게 feature representation을 학습할 수 있는 걸까요?"
AE은 원본을 다시 복원(reconstruct)하는데 사용될 수 있는 특징들을 학습하는 방식을 취합니다.
AE의 과정을 살펴보면, 입력 데이터 x 가 있습니다. encoder는 x를 더 낮은 차원의 z로 매핑시킵니다.
z가 바로 encoder 네트워크의 출력입니다.
입력 데이터로부터 만들어진 특징 z는 두 번째 네트워크인 decoder에 사용됩니다. decoder의 출력은
입력 X과 동일한 차원이고, X과 유사해야 합니다. 즉 우리는 원본 데이터를 복원(reconstruct)하고 싶은 것입니다.
그리고 decoder는 기본적으로 encoder와 동일한 구조를 지닙니다. 즉 이 둘이 대칭적이여야 하는데. 이는 대게 CNN으로 구성합니다.
전체 과정을 다시한번 살펴봅시다. 우선 입력 데이터가 있습니다. 입력 데이터를 endoer에 통과시킵니다.(step 1)
encoder는 가령 4-layers CNN이 될 수 있습니다. 이렇게 encoder는 거쳐서 특징(z)을 얻으면,
z를 decoder에 통과시킵니다. (step 2) decoder는 가령 upconv 네트워크일 수 있습니다. 데이터를 다시 복원하는 단계이죠
CNN모델로 AE를 설계했을 때 encoder는 conv net으로 decoder는 upconv net으로 설계하는 이유는, encoder는
고차원 입력(x)을 받아 저차원 특징(z)으로 변환해야 하는 반면 decoder는 저차원 특징(z)을 고차원으로 복원해야 하기 때문입니다.
지금까지 말씀드렸던것 처럼 입력을 다시 복원하기 위해서는 L2 같은 loss 함수를 이용합니다.
L2 loss는 "복원된 이미지의 픽셀 값과 입력 이미지의 픽셀 값이 서로 같았으면 좋겠다" 라는 의미를 담고 있습니다.
여기에서 중요한점은, 앞서 질문내용에도 있었지만 AE에서 loss 함수를 사용하기는 하지만
AE의 학습과정에서 추가적인 레이블을 필요하지 않다는 것입니다.
우리가 가진것 이라고는 (레이블이 없는) 학습 데이터뿐이며, 학습 데이터 x만으로 네트워크도 통과시키고 Loss도 계산합니다.
AE에서는 학습을 끝마치면 decoder는 버립니다.
decoder는 training time에 입력을 복원해서 loss 함수를 계산하는 용도로만 쓰입니다.
결국 encoder만 가져다 쓰는데, encoder가 학습한 특징 매핑을 교사학습 모델의 초기값으로 사용할 수 있습니다.
encoder가 입력(x)을 특징공간(z)에 매핑시키고나면 그 위로 추가적인 분류기를 붙힙니다.
클래스 레이블을 출력해야 하는 분류 문제로 바뀌는 것이고, 이 경우 Loss함수는 Softmax이고, 추가적인 레이블도 필요합니다.
AE는 많은 레이블링되지 않은 데이터로부터 양질의 general feature representation을 학습할 수 있는 장점이 있습니다.
이렇게 학습시킨 feature representation을 데이터가 부족한 교사학습 모델의 초기 가중치로 이용할 수 있는 것입니다.
여러분이 지난 강의와 과제에서 접했겠지만, 소량의 데이터로는 학습하기 힘들었습니다.
과적합(overfitting) 과 같은 다양한 문제가 있었죠
이 경우 AE는 교사학습 모델이 더 좋은 특징으로 초기화될 수 있도록 도와줍니다.
정리해보면 AE는 입력을 복원하는 과정에서 특징을 잘 학습했고 학습된 특징은 교사학습 모델의 초기화에 이용할 수 있었습니다.
우리는 이러한 AE의 특징을 살펴보며 AE가 학습 데이터의 vatiation를 잘 포착해낼 수 있다는 직관을 가질 수 있었습니다.
즉 잠재 변수인 벡터 z가 학습 데이터의 variation을 잘 가지고있는 것입니다.
그러면 자연스럽게 이런 질문이 따라옵니다. "유사한 방식으로 새로운 이미지를 생성해 낼 수는 없을까?"
자 이제부터는 variational autoencoders에 대해서 다뤄보겠습니다.
AE와는 관점이 조금 다릅니다. 이제는 새로운 데이터를 생성할 것이고, 이를 위해 모델로부터 데이터를 샘플링할 것입니다.
우선, 혹시 autoencoder에 대해서 질문 있으신가요?
그럼 variational autoencoders 시작하겠습니다.
VAE에서는 학습 데이터 xi가 있습니다. i = 1 ~ N 까지 있죠
이 학습데이터가 우리가 관측할 수 없는 어떤 잠재 변수 z (latent representation Z)에 의해 생성된다고 가정합니다.
여기서의 직관은 z는 어떤 벡터입니다.
이 벡터 z의 각 요소들은 데이터의 변동 요소들을 (some factor of variation) 잘 포착해내고 있는 것입니다.
즉 벡터z가 다양한 종류의 속성들을 담고 있는 것인데 가령 얼굴을 생성할때의 특성이라고 하면
생성된 얼굴이 얼마나 웃고있는지, 눈썹의 위치, 머리의 방향 등이 될 수 있습니다.
이러한 속성들이 모두 학습될 수 있는 잠재된 요소라고 할 수 있습니다.
생성 과정에서는 z에 대한 prior로부터 샘플링을 수행할 것입니다.
얼마나 웃고있는지와 같은 속성을 담기 위해서는 이러한 속성들이 어떤 distribution을 따르는지에 대한 prior를 정의해야 합니다.
가령 z에 대한 prior로 gaussian distribution을 선택할 수도 있습니다.
그리고 conditional distribution, P(x given z) 로부터 샘플링하여 데이터 X를 생성해냅니다.
이를 위해서는 우선 z를 먼저 샘플링하고 z를 이용해서 이미지 X를 샘플링합니다.
이 생성 모델의 true parameters는 theta star 입니다.
prior와 conditional distributions에 대한 parameter가 있습니다.
자 이제 생성모델이 새로은 데이터를 잘 생성하게 하러면 true parameter를 잘 추정해야 합니다.
자 그러면 이 모델을 어떻게 설계하면 좋을까요?
이제 생성 과정을 잘 모델링 할 차례인데 앞서 우리는 prior인 P(z)는 단순한 모델을 선택하기도 했습니다.
가령 Gaussian 처럼 말이죠. 잠재적인 속성들을 위한 prior로 Gaussian을 선택하는 것은 합리적입니다.
하지만 conditional distribution, P(x given z) 는 조금 더 복잡합니다.
왜냐하면 우리는 p(x given z)를 가지고 이미지를 생성해야 하기 때문입니다.
우리가 앞서 했던것 처럼, P(x given z)와 같은 복잡한 함수는 neural network로 모델링하면 됩니다.
P(x given z)와 같은 복잡한 모델에는 neural network가 제격입니다.
자 이제 이렇게 설계된 네트워크를 decoder network라고 하겠습니다.
decoder는 어떤 잠재 변수(z)를 받아서 이미지로 디코딩하는 역할을 합니다.
이 모델을 어떻게 학습시킬 수 있을까요?
모델들의 파라미터들을 추정하기 위해서는 모델을 학습시킬 수 있어야겠죠
자 다시 fully visible networks인 pixelRNN/CNN 에서의 전략을 떠올려봅시다.
가장 쉬운 방법은 모델 파라미터가 학습 데이터의 likelihood를 최대화하도록 학습시키는 것입니다.
VAE의 경우에는 잠재 변수 z가 있었습니다.
P(x)는 모든 z에 대한 기댓값으로 나타냈습니다. 여기 있는 것 처럼 말이죠. 잠재변수 z가 있습니다.
자 그럼 이 likelihood p(x)를 최대화시키려고 할 때 무엇이 문제일까요?
지금까지 했던 것 처럼 그레디언트를 계산하고 likelihood를 최대화시키면 되는 것 아닐까요?
[학생이 답변]
네 맞습니다. 위 적분식은 계산을 할 수 없습니다. (intractable)
이제 조금 더 자세히 살펴보도록 하겠습니다.
자 여기 데이터에 대한 likelihood가 있습니다. 첫 번째 항은 p(z)입니다.
앞서 p(z)의 prior는 gaussian prior로 정했습니다. 여기까지는 문제 없습니다.
P(x given z)는 우리가 정의한 decoder neural network입니다.
따라서 z가 주어지기만 한다면 모든 p(x given z)을 얻어낼 수 있습니다.
p(x given z)는 neural network의 출력입니다.
그렇다면 문제가 어디에서 발생하는 것일까요?
저 캐릭터가 원래 저렇게 생기진 않았는데 변환이 잘못됐는지 울고있는 검은 유령 모양이 되었네요 :(
우리는 "모든 z"에 대해서 p(x given z)를 계산하고 싶지만, 계산할 수 없다는 것입니다(intractable).
우리는 이 적분식을 계산할 수 할 수 없습니다.
따라서 data likelihood을 계산할 수 없습니다. (intractable)
posterior density로 나타내보면 p(z gien x) = p(x given z) * p(z) / p(x)
와 같이 베이즈 룰로 나타낼 수 있습니다.
하지만 이 경우 또한 계산하기 어렵습니다.
P(x given z) 나 p(z)는 괜찮지만 p(x)에 들어가는 적분이 계산이 힘듭니다.
따라서 우리는 여러모로 p(x)를 직접 최적화하기는 힘듭니다.
이 모델을 학습시키기 위한 해결책으로는
decoder network이 p(x given z) 말도고 추가적인 encoder network를 정의하는 것입니다.
encoder는 q(z given x) 입니다. encodr를 이용해서 입력 x를 z로 인코딩할 것입니다.
이 encoder네트워크를(q) 통해서 p(z given x)를 근사시키는 것입니다.
이렇게 정의한 posterior density 항은 계산이 가능합니다.
이렇게 p(z given x)를 근사시키는 추가적인 네트워크(q)를 사용하면
data likelihood의 하안(lower bound)을 구할 수 있고, 이는 계산이 가능하므로 최적화로 풀 수 있게됩니다.
자 우선 encoder/decoder 네트워크에 대해서 조금 더 구체적으로 설명해 드리도록 하겠습니다.
VAE에서 우리가 하고싶은 것은 데이터의 확률론적 생성 (probabilistic generation)모델을 만들고싶은 것입니다.
앞서 다뤘던 autoencoder에서는 endoer에서 입력 x를 받아 z를 만들고 decoder에서 z를 받아 다시 이미지를 생성했습니다.
VAE도 기본적으로 encoder/decoder 구조입니다. 그리고 여기에 확률론적인 의미가 가미됩니다.
아 우선 파라미터 phi를 가진 encoder network q(z given x)를 살펴보겠습니다. encoder의 출력은
평균과 (대각) 공분산 입니다. (mean & diagonal covatiance of z given x)
이 값들이 encoder network의 출력입니다.(왼쪽 초록색 박스 두개) 이와 동일하게 -
이제 decoder network를 살펴보면 z부터 시작해서 평균과 (대각)공분산을 출력으로 합니다.
( p(x given z) 에서 x의 차원은 입력 x와 동일합니다. )
decoder에는 파라미터인 theta가 있습니다. (encoder와 다른 파라미터임)
그렇다면, 실제로 "z given x" 와 "x given z"를 얻으려면 이들의 분포로부터 샘플링해야만 합니다.
따라서 encoder/decoder network는 각각 z와 x에 대한 분포를 생성해야 하며
실제 값을 뽑으려면 이 분포로부터 샘플링을 해야 합니다.
여기 그림을 보시면 이런 구조로 어떻게 새로운 데이터를 샘플링하고 생성해 낼 수 있는지 알 수 있습니다.
그리고 encoder/decoder networks를 다른 용어로 부르기도 합니다.
encoder network의 경우에는 "recognition"/"inference" network 부르기도 합니다.
왜냐하면 encoder는 (z given x) 라는 잠재 변수를 "추론하는 (inference)" 네트워크이기 때문입니다.
그리고 decoder는 "생성(generation)" 네트워크 라고 하기도 합니다.
generation network 라는 용어를 보실수도 있습니다.
자 이제 encoder/decoder networks를 준비해 놨으니 다시 data likelihood 문제로 돌아가봅시다.
우선 data likelihood인 p(x)에 log를 취할 것입니다. ( log p(x) )
자 이제 log p(x)가 있습니다.
그리고 p(x)에다가 z에 대한 기댓값(expectation)을 취합니다.
z는 encoder network로 모델링한 q(z given x) 분포로부터 샘플링한 값입니다.
log p(x)에 Expectation을 취할 수 있는 이유는 p(x)가 z에 독립적이기 때문입니다.
자 여기 z에 대한 기댓값(expectation)에 대한 부분은 잠시 후에 다시 살펴보도록 하겠습니다.
자 이제 이 식을 확장해서 베이즈 룰을 적용해봅시다. log[p(x given z) p(z) / p(z given x)]
자 여기에 어떤 상수를 곱해줄 것입니다. (Multiply by constant)
q(z given x) / q(z given x) 를 곱해줍니다. 어짜피 1을 곱해주는 것이죠
1을 곱해주므로 바뀌는 건 없지만 나중에 도움이 될 것입니다.
그리고 이제 식을 세 개의 항으로 나눠줍니다.
여러분들께서 나중에 직접 유도해보시면 좋겠습니다. 기본적인 로그 공식으로 유도할 수 있습니다.
이렇게 나눠주면 각 세개의 항을 각기 다르게 해석할 수 있습니다. (nice meanings)
자 그럼 나눠진 세 개의 항을 살펴보자면 첫 번째 항은 E[log p(x given z)] 입니다.
그리고 KL 항이 두 개 있습니다.
간단히 설명드리면 KL divergence는 두 분포가 얼마나 가까운지를 알려줍니다.
여기에서는(첫 번째 KL) q(z given x)와 p(z)가 얼마나 가까운지를 알려줍니다.
KL의 수식은 바로 위의 Expectation과 동일합니다.
KL divergence는 분포간의 거리를 측정하는 척도라고 할 수 있습니다.
자 이렇게 해서 KL 항들도 한번 살펴보았습니다.
자 그럼 이 세 가지 항을 다시 한번 살펴보겠습니다.
p(x given z)는 decoder network 입니다.
이 첫 번째 항은 샘플링을 통해서 계산할 수 있습니다.
이런 샘플링 과정에서 미분이 가능하도록 하는 "re-parametrization trick" 이라는 기법이 있습니다.
더 관심 있으신 분들은 논문을 살펴보시기 바랍니다.
어쨋든 우리는 첫 번째 항은 계산할 수 있습니다.
자 그리고 두 번째 항을 살펴봅시다. 두 번째 항은 두 가우시안 분포 간의 KL divergence 입니다.
우선 q(z given x)는 encoder에서 발생하는 분포로 평균/공분산을 가지는 가우시안 분포입니다.
그리고 prior p(z) 또한 가우시안입니다.
참고로 KL divergence 에서 두 개의 분포가 모두 가우시안이면 closed form solution으로 풀 수 있습니다.
자 그리고 마지막으로 세 번째 항을 보겠습니다. q(z given x)와 p(z given x)간의 KL 입니다.
앞서 p(z given x)는 계산할 수 없는 항 이라고 했습니다. (untractable)
p(z given x)를 계산할 수 없었기 때문에 q로 근사시킨 것이죠 (variational inference가 이 부분에서 들어감)
따라서 이 항은 여전히 문제가 됩니다.
하지만 우리에게 단서가 하나 있는데, KL divergence는 두 분포간의 거리를 나타내므로, 정의로 보면 항상 0보다 크다는 사실입니다.
따라서 앞의 두 항만 가지고 잘 해보자는 관점으로 본다면
앞의 두 항은, 그레디언트를 이용해 최적화시켜서 실질적으로 계산할 수 있는 하안(lower bound)가 된다는 점입니다.
p(x given z)는 미분가능하고 (1), 두번째 KL 항도 close form solution 으로 미분가능합니다(2).
이 값이 "Tractable lower bound"인 이유는, 맨 오른쪽 세 번째 항이 0보다 크거나 같이 때문입니다.
자 이렇게 lower bound를 구했습니다.
자 이제 VAE를 학습시키기 위해서는, 앞서 구한 lower bound가 최대화되도록 최적화시키면 됩니다.
다시 말해, data likehood의 lower bound를 최적화시키는 것입니다.
이는 data likelihood가 적어도 우리가 최대화시킨(최적화시킨) lower bound 보다는 항상 높을 것임을 의미합니다.
자 이제 lower bound를 최대화시키기 위해서는 파라미터 theta와 phi를 구해야 합니다.
자 그럼 lower bound 항에 대한 직관을 생각해보면
첫 번째 항은 모든 샘플 z에 대한 기댓값(expectation)입니다.
z는 encoder의 출력입니다. encoder로 z를 샘플링하고, 모든 z에 대해서 p(x given z)의 기댓값을 구합니다.
따라서 복원(reconstruction) 에 대한 것입니다.
첫 번째 항이 말하고자 하는 것은, 첫 번째 항의 값이 크다는 것은 likelihood p(p given z)가 크다는 것이고
이 값이 크다는 것은 데이터를 잘 복원해내고 있다는 것을 의미합니다.
앞서 Autoencoder에서 다뤘던 것과 유사합니다.
두 번째 항이 말하고자 하는 것은 KL divergence가 작아야 한다는 것입니다.
우리가 근사시킨 분포(q)와 prior의 분포(p)가 최대한 가까워야 합니다.
다시말해 잠재 변수 z의 분포가 prior 분포(가우시안)와 유사했으면 좋겠다는 뜻이죠
여기까지 질문 있으신가요?
여기에는 수학적인 내용이 많아서, 관심 있으신분들은 관련 내용을 별도로 찾아보여야 할 것입니다.
질문있나요?
[학생이 질문]
질문은 "왜 잠재변수 z와 prior를 가우시안으로 명시해 주는지" 입니다.
그 이유는, 우선 우리는 지금 "생성 과정"을 어떻게 정의할 것인가를 다루고 있습니다.
생성 시 z를 샘플링하고, 이를 바탕으로 x를 샘플링합니다.
데이터 내의 잠재적인 속성들이 가우시안을 따를 것이라고 정의하는 것이 합리적(reasonable)입니다. 이를 바탕으로 모델을 최적화합니다.
자 그럼 이제 lower bound도 구했으니 이를 통해서 VAE를 학습하는 과정에 대해서 살펴보겠습니다.
우리는 이 lower bound를 최대화하길 원합니다.
우선은 forward pass 과정입니다. 입력 데이터 X가 있을 것입니다. 미니배치로 있겠죠
입력 데이터를 encoder에 통과시키면 q(z given x)를 얻을 수 있습니다.
여기에서 계산한 q(z given x)는 KL divergence를 계산할때 이용할 수 있습니다.
q(z given x)를 구헀으면 이 분포로부터 잠재 변수 z를 샘플링합니다.
그리고 샘플링한 z를 decoder에 통과시킵니다.
decoder network의 출력 p(x given z)에 대한 평균과 분산입니다. 이 분포를 바탕으로 샘플링을 할 수 있을 것입니다.
이렇게 샘플링을 하면 샘플 출력이 만들어질 것입니다.
그리고 training time에는 log p(학습 이미지 given z)가 최대가 되도록 학습하면 됩니다.
이 Loss 함수가 말하고자 하는 것은 복원된 이미지에 대한 likehood가 최대가 되었으면 좋겠다는 것입니다.
이런 식으로 모든 미니배치에 대해서 forward pass를 계산합니다.
이렇게 구한 모든 항은 미분이 가능하므로 backprop할 수 있습니다. 그레디언트를 계산하여 -
encoder/decoder의 파라미터 phi와 theta를 업데이트하고 이를 통해 train data likelihood 를 최대화시킵니다.
VAE를 학습시키고나면 데이터 생성 시에는 decoder network만 필요합니다.
앞서 train time에서는 z를 posterior였던 p(z given x)에서 샘플링했습니다. 반면 생성과정에서는
posterior가 아닌 piror(Gaussian)에서 샘플링합니다.
그리고 이를 바탕으로 데이터 X를 샘플링합니다.
여기 MNIST 예제가 있습니다. VAE를 MNIST로 학습시키고 샘플들을 생성시킨 결과입니다.
앞서 변수 z가 데이터의 잠재적인 속성들을 나타낼 수 있다고 말씀드렸습니다.
z에는 우리가 해석할 수 있을만한 다양한 의미가 담길 수 있습니다.
여기 데이터 매니폴드가 있습니다. 2차원 z공간입니다.
2차원 z 분포에서 적절한 백분위 범위에서 Varry Z1과 Vary Z2를 뽑아낸 것입니다.
오른쪽 이미지를 보시면 z1과 z2의 조합으로 생성된 이미지들을 보실 수 있습니다.
z1과 z2의 값이 변함에 따라 이미지도 아주 부드럽게(smoothly) 변하고 있는 것을 보실 수 있습니다.
그리고 prior z는 diagonal covariance를 가정했기 때문에 (각 차원을 independent 하다고 가정)
z의 각 차원이 독립적이며 이로 인해 각 차원마다 독립적인 해석가능한 요소들이 인코딩될 수 있습니다.
여기 얼굴 이미지의 예를 보면 Vary z1은 위아래로 웃음의 정도(the amount of smile)가 바뀌고 있습니다.
위로 갈수록 찡그리고, 아래로 갈수록 웃고 있습니다. 그리고 vary Z2를 살펴보면
좌우를 보시면 되는데, 머리의 위치가 변하는 것을 볼 수 있습니다. 한쪽 방향에서 다른 방향으로 얼굴의 위치가 변하고 있습니다.
이를 통해 알수있는 점은, VAE를 학습시킨 결과, z라는 변수가 좋은 feature representations일 수 있다는 점입니다.
z에는 해석 가능하고 아주 다양한(미소, 얼굴위치) 의미론적인 요소들이 잘 인코딩되어 있기 때문입니다.
따라서 앞서 학습시킨 q(z given x) encoder network에 새로운 입력 x를 넣어서 -
z 공간으로 매핑시키면, 이 특징벡터를 classification이나 다른 테스크에 사용할 수도 있습니다.
VAE로 생성한 이미지들을 조금 더 살펴보겠습니다.
왼쪽은 CIFAR-10 데이터셋으로 학습시킨 결과이고 오른쪽은 얼굴 이미지를 학습시킨 결과입니다.
지금까지 살펴본 것 처럼 일반적으로 VAE가 이미지들을 잘 생성해 내기는 하지만
가장 큰 단점이 있다면 VAE로 생성한 이미지들은 원본에 비해서 블러(blurry)하다는 점입니다.
특히나 얼굴 이미지를 보시면 확연히 그렇습니다. 이 문제(blurry)는 지금도 아주 활발히 연구되고 있습니다.
VAEs를 요약해보겠습니다. VAE는 autoencoders의 확률론적 변형 버전입니다.
AE는 deterministic하게 x를 받아 z를 만들고 다시 x를 복원했다면
VAE는 데이터를 생성해 내기 위해서 분포와 샘플링의 개념이 추가되었습니다.
그리고 계산할 수 없는(intractable) 분포를 다루기 위해서 하안(lower bound)를 계산했습니다.
variational lower bound 죠. "variational"은 계산한 수 없는 형태를 계산할 수 있도록 근사시키는 방법을 의미합니다.
variational autoencoder라고 하는 이유입니다. ( p(z given x) 를 계산못하니 q(z given x)로 근사)
VAE와 같은 접근방식의 이점은 생성 모델에 대한 원칙적 접근(principled approach) 방법이라는 점과
모델에서 q(z given x)를 추론한다는 점입니다.
q(z given x)은 다른 테스크에서도 아주 유용한 feature representations이 될 수 있습니다.
VAE의 단점이 있다면, likelihood의 하안(lower bound) 을 계산한다는 점입니다. 물론 어느정도는 괜찮습니다.
일반적으로 하안(lower bound) 만으로도 좋은 방향으로 이끌 수 있고, 이에 대한 많은 이론이 존재합니다.
그렇기 때문에 어느정도는 괜찮을지 몰라도. 엄밀하게는 pixelRNN/CNN 같이 직접 최적화하는 방법보다는 부족합니다.
그리고 GAN과 같은 다른 SOTA 생성모델에 비해서는 생성된 샘플이 블러하고(blurry), 퀄리티가 낮은 경향이 있습니다.
VAEs는 여전히 아주 활발하게 연구되고있는 분야입니다.
가령 좀 더 유연한 근사함수(approximations) 대한 연구가 있습니다.
단순히 diagonal Gaussian을 사용하지 말고 richer approximate posteriors를 이용해보자는 것이죠
그리고 또 한가지는 잠재변수에 더 많은 구조적인 정보들을 담으려는 시도가 있습니다.
우리가 배운건 잠재 변수의 각 차원이 서로 독립적이었지만
사람들은 직접 구조를 모델링하고 다양한 구조들을 서로 엮기도(grouping) 합니다.
좋습니다 질문있나요?
[학생이 질문]
질문은 "잠재변수(latent variable)의 차원 수를 정해줘야 하는지" 입니다.
네 맞습니다. 직접 명시해 줘야 합니다.
자 지금까지 pixelCNN과 VAE에 대해서 다뤄보았습니다. 세 번째는 아주 유명한 생성모델죠 GAN에 대해서 다뤄보겠습니다.
앞서 살펴본 pixelRNN/CNN은 계산 가능한(tractable) 확률분포(density)를 가정했습니다.
그리고 이를 이용해서 학습 데이터의 likelihood를 최적화시켰습니다.
반면 VAEs의 경우는 잠재변수 z를 두고 생성 과정을 정의했습니다.
잠재변수 z는 많은 이점이 있지만, 결국 VAE는 계산할 수 없는(intractable) 확률분포를 가정하기 때문에
likelihood를 직접 최적화시키지 못하고 대신 하안(lower bound)를 최적화시켰습니다.
자 그렇다면 확률분포를 직접(explicitly) 모델링하는 방법을 아얘 포기하면 어떨까요?
사실 우리가 생성모델에게 원하는 것은 샘플링을 잘하는 능력입니다. 우리가 가진 분포에서 샘플링만 잘하면 그만입니다.
이런 접근법이 바로 GAN입니다.
GAN에서는 우리가 직접 확률분포를 모델링하지 않습니다.
GAN에서는 게임이론의 접근법을 취합니다.
GAN에서는 2- player game 이라는 방식으로 학습 분포를 학습합니다. 앞으로 자세히 배울 내용입니다.
GAN에서 하고자 하는 것은 (set up) 복잡한 고차원 학습 분포로부터 샘플링을 하는 것입니다.
하지만 분포에서 샘플을 만들어내는 과정에 대해서 생각해보면 이를 직접 할 수 있는 방법은 없습니다.
우리가 가진 분포가 아주 복잡하기 때문에 여기에서 직접 샘플링을 하는 것은 불가능합니다.
GAN에서의 해결책은. 우선 우리는 gaussian random noise같은 더 단순한 분포에서는 샘플링을 할 수 있을 것입니다.
그리고 단순한 분포에서 우리가 원하는 학습 분포로 변환(transformation)하는 함수를 배우고자 하는 것입니다.
질문있나요? 질문은 "여기에서 복잡한 분포를 어떻게 표현하는지?" 입니다.
Neural network입니다. 누군가가 답해주셨네요
우리는 보통 복잡한 함수나 변환를 모델링할때 neural network를 사용합니다.
GAN 에서는 입력으로 random noise 벡터(z)를 받습니다. 벡터의 차원 수 우리가 직접 명시해줍니다.
그리고 입력z가 생성 네트워크를 통과하면 학습 분포로부터 직접 샘플링된 값을 출력합니다.
따라서 모든 random noise 입력이 학습 분포의 샘플에 매핑되길 원하는 것입니다.
GAN을 학습시키는 방법으로 two player game을 살펴볼 것입니다.
자 두 명의 플레이어가 있습니다. 하나는 generator이고 다른 하나는 discriminator입니다.
generator는 "플레이어1" 로 참여하여 사실적인 이미지를 생성하여 discriminator를 속이는 것이 목표입니다.
"플레이어2"인 discriminator 는 입력 이미지가 "실제"인지"거짓" 인지를 구별하는것이 목표입니다.
discriminator는 이미자가 generator가 만든 가짜 이미지 (위조 이미지)인지 아닌지를 가능한 잘 구분해 내야 합니다.
다음 이미지를 살펴보겠습니다.
random noise가 generator의 입력으로 들어갑니다.
generator는 이미지를 생성해 내는데, 이 이미지는 generator가 만들어낸 "가짜 이미지" 입니다.
그리고 학습 데이터에서 나온 실제 이미지도 있습니다.
discriminator는 실제/가짜 이미지를 구별할 수 있어야 합니다.
discriminator의 출력은 이미지가 진짜(real)인지 가짜(fake)인지입니다.
GAN의 아이디어는 discriminator가 아주 잘 학습이 되서 진짜인지 가까인지를 아주 잘 구별할 수 있다면
generator는 discriminator를 속이기 위해서 더 실제같은 가까 이미지를 만들 수 있어야 합니다.
이를 통해 우리는 아주 좋은 generative model을 만들 수 있습니다.
이렇게 생성된 이미지는 학습 데이터셋에 있을 것 처럼 생긴 이미지처럼 보일 것입니다.
자 이렇게 두 플레이어가 준비가 되었습니다. 이제는 "minimax game"의 형태로 같이(jointly) 학습시킬 차례입니다.
자 여기 "Minimax objective function"이 있습니다.
이 object function에서는 generator network 인 G의 파라미터인 theta_g는 최소화시켜야 합니다.
반면 Discriminator network인 D의 파라미터인 theta d는 최대화시켜야 합니다.
이 함수에서 말하고자 하는 것은
우선, 데이터에 대한 Expectation E[log D(x)] 가 있습니다.
log D(x)는 실제(real) 데이터 x에 대한 discriminator의 출력 값입니다.
log D(x)는 실제 데이터(x)가 데이터 분포 p_data에 속할 likelihood입니다.
그리고 두번째 항을 살펴보겠습니다. p(z)를 따르는 z에 대한 기댓값(expectation)에서 z ~ p(z)의 의미는
generator에서 샘플링한다는 의미입니다. 그리고 D(G(z))는 생성된 가짜 이미지(G(z))에 대한 discriminator의 출력입니다.
그렇다면 가짜 이미지인 G(z)에 대한 discriminator의 출력은 무엇일까요?
우리가 하려는 것을 다시 생각해보면 우선 discriminator는 objectrive function를 최대화 해야 합니다.
최대화시키는 파라미터 theta d를 찾아야 합니다. D(x)의 경우에는 실제 데이터이므로 값이 1이면 좋습니다.
반면 D(F(x))는 가짜 데이터에 대한 것이므로 0일수록 좋습니다.
그리고 discriminator의 입장에서 objective function을 최대화시킨다는 것은 진짜인지 가짜인지를 잘 구별해낸다는 의미입니다.
discriminator는 기본적으로 실제/가짜 데이터인지를 분류합니다.
반면 generator는 objective functuon이 작을수록 좋으므로 D(G(z))가 1에 가까울수록 좋습니다.
D(G(z))가 1에 가까우면, 1 - D(G(z)) 이므로 값이 작아집니다. 이렇게 작아진다는 의미는
discriminator가 가짜 이미지를 진짜라고 잘못 분류하고 있다는 의미입니다.
다시 말해 generator가 진짜 같은 이미지를 잘 만들고있다는 것입니다.
이 부분이 GAN에서 가장 중요한 부분입니다. 혹시 이와 관련된 질문 있나요?
[학생이 질문]
질문은 GAN의 목적이 "generator는 진짜 같은 이미지를 생성하게 하고 discriminator가 이걸 구별 못하게 하는 것인지" 입니다. 맞습니다.
질문은 "이 네트워크를 학습시키기 위해서 레이블 데이터가 필요하지 않은지" 입니다.
학습 과정을 잠시후 배우겠지만, GAN은 기본적으로 비교사 (unsupervised) 학습에 해당합니다. 레이블이 필요하지 않습니다.
generator에서 생성된 데이터의 레이블은 가짜 이미지라는 의미에서 0입니다.
그리고 실제 학습 이미지는 진짜 이미지이기 때문에 레이블이 1입니다.
discriminator의 Loss함수가 이 레이블을 이용합니다.
discriminator의 입장에서는 generator가 만든 이미지라면 0 실제 이미지라면 1로 분류하는게 좋습니다.
따라서 GAN은 추가적인 레이블이 필요하지 않습니다.
[학생이 질문]
질문은 "generator를 학습시키기 위한 레이블이 discriminator의 출력인지" 입니다.
generator는 분류는 하는 네트워크가 아닙니다.
objective function을 다시한번 살펴보면 generator는 D(G(z))의 값이 높았으면 좋은 것입니다.
이 경우 discriminator를 고정시키고 generator의 파라미터를 D(G(z))가 높도록 학습시킵니다.
이렇게 generator를 학습시키는 경우에는 discriminator를 고정하고 backprop을 진행합니다.
자 이제 GAN을 학습시켜봅시다.
GAN을 학습시키려면 generator와 discriminator를 번갈아가면서 학습시킵니다. discriminator의 경우에는
objective function가 최대가 되는 theta를 학습하기 위해 gradient ascent를 이용합니다.
그리고 generator는 반대로 gradient descent를 이용하죠
gradient descent를 통해서 파라미터 theta_G를 학습시켜서 object function이 최소가 되도록 합니다.
Generator를 학습시키는 경우에는 오른쪽 항만 있으면 됩니다. 오른쪽 항만이 generator의 파라미터인 theta_g가 있습니다.
지금까지 GAN을 어떻게 학습시킬지 살펴보았습니다.
(two player, minimax) game을 이용해서 discriminator/generator를 번갈아가면서 학습시키죠
generator는 discriminator를 속이려고 합니다.
하지만 중요한 점이 하나 있는데, 실제로는 generator의 objective function이 학습이 잘 안된다는 점입니다.
그 이유는 loss landscape을 살펴보면 알 수 있습니다.
지금 보이는 loss landscape는 D(G(x))의 loss landscape 입니다.
generator는 (1 - D(G(x))) 의 값이 높을수록 좋습니다. (1 - D(G(x))) 를 그래프로 그려보면 모양이 다음과 같습니다.
우리는 Loss가 최소가 되길 원하는데 Loss의 기울기가 오른쪽으로 갈수록 점점 커집니다.
D(G(x))가 1에 가까울수록 기울기도 크다는 의미입니다.
다시말해 discriminator가 generator를 잘 속이고 있으면 그레이언트도 점점 더 커진다는 의미입니다.
반면 생성된 샘플이 좋지 않을때, 즉 generator가 아직은 잘 학습되지 않은 경우라면
discriminator가 쉽게 구분할 수 있는 상태이므로 X 축 상에서 0 근처인 상태입니다.
이 지점에서는 그레디언트가 상대적으로 평평합니다.
이것이 의미하는 바는, 그레디언트가 generator가 생성을 이미 잘 하고 있는 지역에만 몰려있다는 의미입니다.
하지만 우리는 당연히 샘플이 안좋은 경우에 더 학습을 더 많이 할 수 있어야(그레디언트가 커야) 합니다.
이러한 이유로, generator를 학습시키는 상당히 어렵습니다. 학습 능력을 향상시키기 위해서는
그레디언트를 개선시키기 위해서 objective function을 조금 변경해줘야 합니다.
genrator에서도 gradient ascent를 이용할 것입니다.
앞서 수식에서처럼 discriminator가 정답을 잘 맞출 likelihood를 최소화 시키는 방법 대신에
반대로, discriminator가 틀릴 likelihood를 최대화 시키는 쪽으로 학습시킬 것입니다.
이는 objective function을 log(D(G(x))를 최대화시키는 것으로 구현할 수 있습니다.
우하단 그래프를 살펴보시면(초록색) 이제 음수가 붙어야 합니다(-log D(G(x))
이제는 Generator를 최적화할때 뒤집어진(flip) object function을 최대화시킬 것입니다.
오른쪽 그래프(초록색)을 살펴보면 이제는 왼쪽의 그레디언트가 커졌습니다. 안 좋은 샘플을 생성하고 있는 부분입니다.
그리고 좋은 샘플들을 생성해내고 있는 부분인 오른쪽이 더 평평해 졌습니다.
따라서 안좋은 샘플들을 만들어내는 곳에서 더 많은 학습이 이루어질 수 있게 되었습니다.
두 objective functions 모두 discriminator를 속이는 목적은 동일하지만, 실제로는 후자가 훨씬 더 잘됩니다.
vanilla GAN의 수식을 따르는 대부분의 GANs은 이 objective function을 사용하고 있습니다.
decriminator/generator를 번갈아서 같이 학습시키는 것은 상당히 불안정합니다.
기본적으로 이렇게 두 네트워크를 동시에 학습시키는 것 자체가 상당히 어려우며, 또한 앞서 말씀드린
loss landscape에 관련한 이슈들 또한 학습 과정에 영향을 미칩니다.
좋은 loss landscapes를 위한 objectrive function 을 설계하고 안정적으로 학습하기 위한 연구들도 아직 활발히 진행중입니다.
자 그럼 앞서 언급했던 내용들을 종합해서 전체 GAN 학습 알고리즘을 살펴보겠습니다.
학습은 반복적으로 진행됩니다.
학습 순서는 우선 discriminator을 조금 학습시키고 그 다음 generator를 학습시키는 방식입니다.
우선 k번 만큼 discriminator를 학습시킵니다.
noise prior Z (p(z))에서 미니배치만큼 노이즈를 샘플링합니다. 그리고 학습 데이터 x에서 실제 샘플을 미니배치만큼 샘플링합니다.
샘플링한 노이즈를 generator에 통과시키면 가짜 이미지가 생성됩니다.
그러면 미니배치 만큼의 가짜 이미지와 미니배치 만큼의 진짜 이미지가 준비됩니다.
discriminator의 그레디언트를 계산할 때 이렇게 준비한 진짜/가짜 이미지를 사용합니다.
그리고 discriminator 파라미터를 업데이트합니다.
그리고 discriminator를 k step만큼 학습시킵니다.
discriminator를 어느정도 학습시키고 나면, 두 번째로 generator를 학습시킵니다.
우선 noise prior, p(z)에서 노이즈를 샘플링합니다.
그리고 샘플링된 노이즈를 generator에 통과시키고 generator를 최적화(학습) 시킵니다.
generator는 가능한 discriminator를 속이려는 방향으로 학습이 될 것입니다.
이런 식으로 discriminator/generator를 번갈아가면서 학습시킵니다.
앞서 discriminator를 학습시킬 때 k 스텝이 있었습니다. 사실 이 부분은 논쟁이 많은 부분입니다.
어떤 사람들은 discriminator/generator를 한번 (k = 1) 씩 학습시키는 편이 좋다는 의견도 있습니다.
반면 어떤 사람들은 generator를 학습하기 전에 discriminator를 더 많이 학습시키는 편이 좋다는 의견도 있습니다.
하지만 정해진 규칙은 없습니다. 사람들의 의견은 각자의 문제에 따라 더 잘되는 방법을 찾아낸 것 뿐입니다.
이런 문제를 완화시키고자 하려는 최근의 연구가 아주 활발합니다. D/G를 번갈아 학습시킬때 그 균형을 효과적으로 잡아보자는 것입니다.
이를 통해 안정적인 학습과 더 좋은 결과를 얻기 위함입니다.
GAN의 안정적인 학습을 위한 방법을 제안하는 논문중 대표적인 예로 "Wasserstein GAN" 이 있습니다.
전체 그림을 다시한번 살펴보겠습니다. GAN setup에서는 generator/discriminator를 학습시켜야 합니다.
우선 generator는 새로운 이미지를 생성시키는 네트워크입니다.
generator는 노이즈 z를 입력으로 받아서 가짜 이미지를 생성합니다.
GAN으로 생성시킨 샘플들을 한번 살펴보겠습니다.
왼쪽에는 MNIST의 예가, 오른쪽에는 얼굴이미지의 예가 있습니다.
그리고 MNIST, face의 맨 오른쪽 이미지들은(노란박스) 바로 옆 생성된 이미지와 가장 가까운 실제이미지(학습이미지)입니다.
이 결과를 보면, 생성 모델이 진짜같은 이미지를 잘 생성해 내며, 이 결과는 단순히 학습 이미지를 외운 결과가 아님을 알 수 있습니다.
original GAN 논문에 있는 CIFAR10 이미지의 예도 있습니다.
2014년에 나온 오래되고 네트워크가 단순한 original GAN 의 결과라서 퀄리티가 좋아보이진 않습니다.
그 당시에는 단순하게 fully connected network 만을 이용했습니다.
original GAN(2014) 이후에 GAN의 성능을 향상시키기 위한 아주 많은 연구가 있었습니다.
A. Radford가 ICLR'16에 발표한 CNN 아키텍쳐를 GAN에 적 용한 연구가 GAN의 성능을 극적으로 끌어올립니다.(DCGAN)
이 논문에서는 GAN이 더 좋은 샘플링을 할 수 있도록하는 전체적인 GAN 아키텍쳐 가이드라인을 제시합니다.
이 슬라이드에서 더 자세한 내용을 확인해 보실 수 있습니다.
여기(DCGAN)에서 GAN에 적용한 CNN 아키텍쳐를 살펴보면
입력 노이즈 벡터 z가 있고 z를 다음과 같은 과정으로 샘플 출력으로 변환(transform)시킵니다.
large CNN 아키텍쳐를 사용한 GAN의(DCGAN) 결과를 보면 상당히 좋습니다.
다음은 침실(bedrooms) 데이터셋으로 학습한 결과입니다.
결과가 아주 realistic하고 fancy합니다.
창문, 스탠드 조명 등 아주 다양한 가구들이 잘 생성되었습니다. 아주 멋있고 이쁘게 잘 생성된 샘플들입니다.
그리고 GAN이 어떤 일을 하려하는지 조금은 해석해볼 수 있을 것입니다.
가령 여기에서는 z 포인트를 두개 잡습니다. z는 두개의 랜덤 노이트 벡터입니다. 그리고 그 사이를 보간(interpolate)해 봅니다.
여기 보이시는 이미지의 각 행들은 두 개의 램던 노이즈 z 를 보간(interpolation)하여 이미지를 생성한 결과입니다.
이 결과를 보시면, 두 이미지간에 아주 부드럽게 이미지가 변하는 것을 알 수 있습니다.
자 그럼 다른 방식으로도 한번 해석해봅시다.
벡터 z가 의미하는 바를 조금 더 이해하기 위해서 벡터 z를 가지고 벡터연산을 해 볼 수도 있습니다.
이 실험해서는, 우선 웃고있는 여성의 이미지를 뽑습니다.
그리고 웃고있지 않은(neutral) 여성의 사진과 웃고있지 않은 남성의 사진도 뽑습니다.
그리고 뽑은 벡터 z 들에 각 평균을 취합니다.(가장 밑)
자 그럼 (웃는 여성의 평균 벡터) - (그냥 여성의 평균 벡터) + (그냥 남성의 평균 벡터) 라는 벡터연산을 수행하면 어떻게 될까요?
웃는 남성을 얻을 수 있습니다.
벡터 연산으로 나온 벡터 z를 가지고 이미지를 생성해보면 웃는 남성 이미지를 얻을 수 있습니다.
다른 예도 한번 살펴보겠습니다. (안경 낀 남성) - (안낀 남성) + (안낀 여성) 은 어떨까요?
안경 낀 여성이 나옵니다.
기본적으로 z를 가지고 다음과 같은 해석이 가능하며, 아주 멋진 샘플 이미지들을 만들어내볼 수 있습니다.
올해는 2017년입니다. GAN의 해라고 할 수 있습니다.
GAN과 관련된 엄청나게 많은 논문들이 발표되었습니다. 그리고 아주 재미있는 결과들도 많았습니다.
좌측에는 GAN을 더 잘 학습시키고 이미지들을 더 잘 생성시키기 위한 모델들이 있습니다.
앞서 우리는 "loss function"과 "더 안정적으로 학습" 에 관해서 다뤘습니다. 여기에서도 이와같은 내용을 다룹니다.
다양한 아키텍쳐에서 아주 좋은 결과를 보여줍니다.
그리고 아래를 보면(BEGAN) 아주 선명한 고해상도의 얼굴 이미지를 보실 수 있습니다.
또한 GAN으로 "source -> target domain 변환" 이나 "conditional GANs"도 가능합니다.
가운데 예제(CycleGAN)은 "source -> target domain 변환"의 예입니다.
맨 위를 보시면(horses -> zebras), source domain은 말(horses)이고, target domain은 얼룩말(zebras)입니다.
이 GAN을 학습시키고 말 사진을 넣으면, 말 사진과 비슷한 사진이 나오지만, 이제는 말이 얼룩말로 변합니다.
자른 예시들도 살펴보면 사과를 오렌지로 바꿔줄 수도 있습니다.
또 다른 예시를 살펴보면 "photo enhancement"에도 적용해 볼 수 있습니다.
평범한 이미지를 넣으면, 아주 비싼 카메라로 찍은듯한 사진으로 변환됩니다. 아주 멋진 블러 이미지를 얻을 수 있습니다.
그리고 아래쪽을 보시면, 장면에 대한 변환도 가능합니다 . 겨울에 촬영한 Yosemite이미지를 여름으로 변환할 수도 있습니다.
이처럼 아주 많은 응용이 가능합니다.
조금 더 살펴보자면, 슬라이드의 오른쪽의 예를 보시면, 텍스트로된 설명을 입력으로 받아서 이미지를 생성하는 GAN 입니다.
a small bird with a pink breast and crown 이라는 문장에 이미지들이 생성된 결과입니다.
edges에 색을 채워넣는 모델도 있습니다. 여러분의 스케치가 조건(conditions)으로 주어지면, 이 스케치의 컬러버전을 생성합니다.
또한, (Pix2Pix) Google Map이미지를 넣으면 Google Earth에 나올법한 이미지들이 생성됩니다.
Google Earth에 나올법한 건물과 나무 등이 보입니다.
이런 예시들은 아주 많습니다. Pix2Pix 웹사이트에 conditional GAN 종류의 예시들을 다양하게 보실 수 있습니다.
웹사이트에 GANs에 관한 더 많은 재미있는 어플리케이션들이 많으니 꼭 가보시기 바랍니다.
올해에는 GAN에 관련한 연구 논문들이 엄청나게 쏟아졌습니다.
주요 GAN 논문 리스트들을 모아놓은 GAN Zoo라는 웹사이트가 있습니다.
왼쪽 열만 A-C 까지 밖에 없습니다. 슬라이에 리스트 전부를 담지도 못하죠. 관심있으신 분들을 꼭 방문해 보시기 바랍니다.
마지막으로, GAN을 실제로 학습시킬때 필요한 팁과 트릭을 담은 웹사이트도 있으니 활용하시기 바랍니다.
GANs을 요약해보겠습니다. GANs은 특정 확률분포를 정의하지 않았습니다. (Implicit density)
대신에 샘플들을 활용한 암묵적인(implicit)방법을 사용했습니다. 그리고 학습에는 게임이론에 기반한 접근방법을 이용합니다.
two player game을 통해서 학습 데이터의 분포로부터 생성 모델을 학습시켰습니다.
GANs의 장점은 generator가 생성한 데이터의 퀄리티가 SOTA라는 점입니다.
단점이라면 학습시키기 까다롭고 불안정하는 점과 objective function을 직접적으로 최적화하는게 아니라는 점입니다.
objective function가 하나 있고, 이를 단순히 backporp해서 학습시켰으면 좋았겠지만
학습 시켜야 하는 네트워크가 두 개나 있었기 때문에 균형을 잘 맞춰서 학습시키기가 다소 불안정했습니다.
VAE에서 있었던 P(x)나 p(z given x) 와 같은 값들을 GAN에서는 구할 수 없다는 단점도 있습니다.
GAN은 여전히 아주 활발이 연구되고 있는 분야입니다. 앞으로도 아주 많은 관련 모델들이 나올 것입니다.
개선된 loss function을 통해 더 안정적인 학습을 하기위한 연구도 있습니다. 가령 Wasserstein GAN이 그 예입니다.
많은 사람들이 기본 모델을 그대로 사용하기도 하고, 또한 LSGAN(Least square's GAN) 등의 모델도 있습니다.
여러분들이 더 살펴보시기 바랍니다. 이렇게 제안된 많은 모델들을 구현할때 엄청 많이 구현을 바꿀 필요가 없습니다.
Loss function만 조금 바꿔주면 학습 시 아주 큰 성능 향상을 얻을 수 있을 것입니다.
여러가지 모델을을 살펴보시기 바라며 과제로도 있으니 실제로 구현해보시기 바랍니다.
그리고 GAN에는 conditional GANs 처럼 아주 다양한 문제 정의 및 응용으로도 많이 연구되고있습니다.
자 오늘 배운 내용을 정리해봅시다. 오늘은 생성모델에 대해서 배워보았습니다.
우리는 크게 세가지 생성모델을 살펴보았습니다. 현재 사람들이 많이 사용하고 연구중인 모델들입니다.
우선 pixelRNN/CNN을 살펴보았습니다. explicit density model 이었습니다.
Pixel RNN/CNN은 likelihood를 직접 최적화하므로 좋은 샘플들을 얻을 수 있었지만, 순차적으로 생성해야 하는 단점이 있엇습니다.
VAE는 likelihood의 하안(lower bound)을 최적화시켰고 아주 유용한 latent representation을 얻을 수 있었습니다.
inference queries가 가능했지만 생성된 샘플들이 엄청 좋지는 않았습니다.
VAE는 아직까지도 아주 활발히 연구중인 분야이며 풀어야할 문제들도 아주 많은 분야입니다.
GAN은 게임이론을 바탕으로하는 학습방법을 취했으며 현재 SOTA성능을 기록하고 있습니다.
하지만 학습하기 까다롭고 너무 불안정했습니다. 그리고 VAE와는 달리 inference queries가 불가능합니다.
그리고 최근에는 이 모델을을 조합하는 시도들도 많습니다.
가령 adversarial autoencoders처럼 말이죠
VAE의 샘플링 퀄리티를 높히기 위해서 추가적인 adversarial loss를 추가하는 방식입니다.
pixel VAE는 pixel CNN과 VAE의 조합입니다. 이런 조합들은 기본적으로 각 모델들의 장점을 최대한 살리면서 조합하려는 시도들입니다.
이번 시간에는 생성모델을 배웠습니다. 다음 시간에는 강화학습 (reinforcement learning)을 배우겠습니다. 감사합니다.